package org.jxf.gps.jt808.message;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.jfk.core.utils.ByteUtils;

public class MessageParser {

	public static byte[] msg2buf(Message msg) {
		byte[] b_flag = { 0x7e };
		byte[] head;
		byte[] body = msg.body;
		byte[] crc;

		byte[] e_flag = { 0x7e };

		byte[] msgId = ByteUtils.intToWord(msg.msgId);

		int attr = msg.body.length;

		attr = attr + msg.cipher;

		if (msg.pkg) {
			attr = attr + 0x2000;
		}

		byte[] msgAttr = ByteUtils.intToWord(attr);

		byte[] mdn = ByteUtils.hexStringToBytes(msg.mdn);

		byte[] sn = ByteUtils.intToWord(msg.sn);

		head = ByteUtils.byteMerger(msgId, msgAttr);
		head = ByteUtils.byteMerger(head, mdn);
		head = ByteUtils.byteMerger(head, sn);

		if (msg.pkg) {
			byte[] pkgTotal = ByteUtils.intToWord(msg.pkg_total);
			byte[] pkgOrder = ByteUtils.intToWord(msg.pkg_order);
			head = ByteUtils.byteMerger(head, pkgTotal);
			head = ByteUtils.byteMerger(head, pkgOrder);
		}

		byte[] buf = ByteUtils.byteMerger(head, body);

		byte c = ByteUtils.genCRC16(buf);

		crc = new byte[1];
		crc[0] = c;
		msg.crc = c;

		buf = ByteUtils.byteMerger(b_flag, buf);
		buf = ByteUtils.byteMerger(buf, crc);
		buf = ByteUtils.byteMerger(buf, e_flag);

		return buf;
	}

	public static Message buf2msg(byte[] buff) {
		if (buff[0] != 0x7e) {
			return null;
		}
		Message m = new Message();
		//获取消息开始标识位
		m.b_flag = buff[0];
		
		//获取消息ID
		byte[] tmp2 = new byte[2];
		tmp2[0] = buff[1];
		tmp2[1] = buff[2];
		m.msgId = ByteUtils.byte2ToInt(tmp2);
		
		//获取消息体属性
		tmp2[0] = buff[3];
		tmp2[1] = buff[4];
		int tmp = ByteUtils.byte2ToInt(tmp2);
		m.length = tmp & 0x03ff; //低10位表示 —— 10位二进制标识包长度。
		m.body = new byte[m.length];
		m.cipher = tmp & 0x1c00;//第4、5、6位表示 —— 0x0000不加密，0x0400 RSA

		if ((tmp & 0x2000) == 0) {//第3位表示是否组包
			m.pkg = false;
			m.pkg_order = -1;
			m.pkg_total = -1;
		} else {
			m.pkg = true;
			tmp2[0] = buff[13];
			tmp2[1] = buff[14];
			m.pkg_total = ByteUtils.byte2ToInt(tmp2);
			tmp2[0] = buff[15];
			tmp2[1] = buff[16];
			m.pkg_order = ByteUtils.byte2ToInt(tmp2);
		}

		//获取终端手机号
		byte[] tmp6 = new byte[6];
		tmp6[0] = buff[5];
		tmp6[1] = buff[6];
		tmp6[2] = buff[7];
		tmp6[3] = buff[8];
		tmp6[4] = buff[9];
		tmp6[5] = buff[10];
		m.mdn = ByteUtils.byteToHexString(tmp6);

		//获取消息流水号
		tmp2[0] = buff[11];
		tmp2[1] = buff[12];
		m.sn = ByteUtils.byte2ToInt(tmp2);
		
		//获取CRC校验码
		m.crc = buff[buff.length - 2];
		
		//获取消息结束标识位
		m.e_flag = buff[buff.length - 1];
		
		int j = 0;
		for (int i = buff.length - 2 - m.length; i < buff.length - 2; i++) {
			m.body[j] = buff[i];
			j++;
		}
		m.mBody = MsgBodyFactory.getMsgBody(m.msgId);
		if (m.mBody != null) {
			m.mBody.fromBuff(m.body);
		}
		return m;
	}


	/**
	 * 平台通用应答
	 * 
	 * @param moMsg
	 * @return
	 */
	public static Message genMoSimpleResp(Message moMsg) {
		Message msg = new Message();
		msg.msgId = 0x8001;
		msg.pkg = false;

		msg.cipher = 0;
		msg.mdn = moMsg.mdn;
		msg.channelInfo = moMsg.channelInfo;
		msg.sn = ByteUtils.byte2ToInt(ByteUtils.longToWord(System.currentTimeMillis()));

		byte[] sn = ByteUtils.intToWord(moMsg.sn);
		byte[] msgId = ByteUtils.intToWord(moMsg.msgId);
		byte[] result = { 0x00 };
		msg.body = ByteUtils.byteMerger(sn, msgId);
		msg.body = ByteUtils.byteMerger(msg.body, result);

		return msg;
	}

	/**
	 * 查询终端参数
	 * 
	 * @param moMsg
	 * @return
	 */
	public static Message genMtGetTmParam(Message moMsg) {
		Message msg = new Message();
		msg.msgId = 0x8104;
		msg.pkg = false;
		msg.cipher = 0;
		msg.mdn = moMsg.mdn;
		msg.length = 0;
		msg.sn = ByteUtils.byte2ToInt(ByteUtils.longToWord(System.currentTimeMillis()));

		return msg;
	}

	/**
	 * 查询位置信息
	 * 
	 * @param moMsg
	 * @return
	 */
	public static Message genMtGetPositionInfo(Message moMsg) {
		Message msg = new Message();
		msg.msgId = 0x8201;
		msg.pkg = false;
		msg.cipher = 0;
		msg.mdn = moMsg.mdn;
		msg.length = 0;
		msg.sn = ByteUtils.byte2ToInt(ByteUtils.longToWord(System.currentTimeMillis()));

		return msg;
	}

	/**
	 * 临时位置跟踪控制
	 * 
	 * @param moMsg
	 * @return
	 */
	public static Message genMtTempPositionTraceCtrl(Message moMsg) {
		Message msg = new Message();
		msg.msgId = 0x8202;
		msg.pkg = false;
		msg.cipher = 0;
		msg.mdn = moMsg.mdn;
		msg.length = 6;
		msg.sn = ByteUtils.byte2ToInt(ByteUtils.longToWord(System.currentTimeMillis()));

		byte[] interval = ByteUtils.intToWord(10);
		byte[] limit = ByteUtils.intToDWord(100);
		msg.body = ByteUtils.byteMerger(interval, limit);

		return msg;
	}

	/**
	 * 文本信息下发
	 * 
	 * @param moMsg
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static Message genMtSendText(Message moMsg)
			throws UnsupportedEncodingException {
		Message msg = new Message();
		msg.msgId = 0x8300;
		msg.pkg = false;
		msg.cipher = 0;
		msg.mdn = moMsg.mdn;

		msg.sn = ByteUtils.byte2ToInt(ByteUtils.longToWord(System.currentTimeMillis()));

		byte[] flag = new byte[] { 0x01 };
		byte[] content = "hello！你好123%￥#768%$".getBytes("GBK");
		msg.body = ByteUtils.byteMerger(flag, content);
		msg.length = msg.body.length;
		return msg;
	}

	
	
	/**
	 * 发送前将0x7e和0x7d进行转义处理
	 * @param buff
	 * @return
	 */
	public static byte[] convert7E7D(byte[] buff){
		
		int j = 0;
		byte[] buff1 = new byte[buff.length*2];
		for (int i = 0 ; i < buff.length ; i++){
			if (buff[i] == 0x7e){
				if (i == 0 || i == buff.length -1){
					buff1[j] = buff[i];
				}else{
					buff1[j] = 0x7d;
					j++;
					buff1[j] = 0x02;
				}
			} else if (buff[i] == 0x7d){
				buff1[j] = 0x7d;
				j++;
				buff1[j] = 0x01;
			} else{
				buff1[j] = buff[i];
			}
			j++;
		}
		byte[] buff2 = new byte[j];
		System.arraycopy(buff1, 0,buff2, 0, j);
		return buff2;
	}
	
	/**
	 * 收到消息后，将转义处理还原成0x7e或0x7d
	 * @param buff
	 * @return
	 */
	public static byte[] recover7E7D(byte[] buff){
		int j = 0;
		byte[] buff1 = new byte[buff.length];
		for (int i = 0 ; i < buff.length ; i++){
			if (buff[i] == 0x7d){
				if (buff[i+1] == 0x01){
					buff1[j] = 0x7d;
					i++;
				}else if (buff[i+1] == 0x02){
					buff1[j] = 0x7e;
					i++;
				}else{
					buff1[j] = buff[i];
				}
			}else{
				buff1[j] = buff[i];
			}
			j++;
		}
		byte[] buff2 = new byte[j];
		System.arraycopy(buff1, 0,buff2, 0, j);
		return buff2;
	}

	

}
